package com.lwl.nio.select;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * Created by liwenlong on 2017/12/6 19:23
 */
public class SelectSockets {

    public static int default_port = 12345;

    public void go() throws IOException {
        int port = default_port;
        System.out.println("Listening on port " + port);
        //获取ServerSocketChannel
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverChannel.socket();
        serverSocket.bind(new InetSocketAddress(port));
        serverChannel.configureBlocking(false);
        //创建选择器
        Selector selector = Selector.open();
        //通道注册到选择器上
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            int n = selector.select();

            if (n <= 0) {
                System.out.println("继续执行...........");
                continue;
            }
            System.out.println("有新的selected key");
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                //Is a new connection coming in?
                if (key.isAcceptable()) {
                    System.out.println("key.isAcceptable........");
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel channel = server.accept();
                    registerChannel(selector,channel,SelectionKey.OP_READ);
                    sayHello(channel);
                }
                // Is there data to read on this channel?
                if(key.isReadable()){
                    System.out.println("key.isReadable........");
                    readDataFromSocket(key);
                }
                // Remove key from selected set; it's been handled
                iterator.remove();
            }
        }
    }

    private void registerChannel(Selector selector,SelectableChannel channel,int ops) throws IOException {
        if(channel == null){
            return;
        }
        channel.configureBlocking(false);
        channel.register(selector,ops);
    }

    private ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
    protected void readDataFromSocket(SelectionKey key) throws IOException {
        SocketChannel socketChannel = (SocketChannel) key.channel();
        int count;
        buffer.clear();
        while ((count = socketChannel.read(buffer)) > 0){
        	byte[] strbytes = new byte[count];
            buffer.flip();
            buffer.get(strbytes);
            String string = new String(strbytes);
            System.out.println(string);
           
            socketChannel.write(ByteBuffer.wrap("hahahahahahaah\r\n".getBytes()));
            buffer.clear();
        }
        if(count < 0){
            socketChannel.close();
        }
    }

    private void sayHello(SocketChannel channel) throws IOException {
        buffer.clear();
        buffer.put("hi there!\r\n".getBytes());
        buffer.flip();
        channel.write(buffer);
    }




}
